home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpat2-1.000
/
xpat2-1
/
xpat2-1.04
/
src
/
X-arrows.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-23
|
10KB
|
316 lines
/*****************************************************************************/
/* */
/* */
/* X patience version 2 -- module X-arrows.c */
/* */
/* Displays hint arrows for the X interface */
/* written by Heiko Eissfeldt and Michael Bischoff */
/* see COPYRIGHT.xpat2 for Copyright details */
/* */
/* */
/*****************************************************************************/
#include "X-pat.h"
GC hintgc;
static int rem_sx = -1, rem_sy, rem_dx, rem_dy;
static int size_x, size_y;
static Pixmap arrow_storage_x = 0, arrow_storage_y, arrow_storage_z;
#ifdef useXlib
void init_arrow(const char *arrowcolor, int arrwidth, int arrheight)
{
/* make GCs for dashed lines or colored lines (to mark cards) */
XGCValues gcv;
long gcflags;
XColor color;
Colormap cmap;
if (arrwidth >= 0 && arrwidth <= 30)
graphic.aw = arrwidth;
if (arrheight >= 0 && arrheight <= 30)
graphic.ah = arrheight;
if (graphic.aw <= 0 || graphic.ah <= 0) {
graphic.aw = graphic.ah = -1;
return; /* no arrows wanted */
}
/* make own gcs for dashed lines */
gcv.background = BlackPixel(dpy, screen);
gcv.graphics_exposures = True;
gcflags = GCForeground | GCBackground | GCGraphicsExposures;
if (graphic.is_color && arrowcolor) {
cmap = DefaultColormap(dpy, screen);
color.flags = DoRed | DoGreen | DoBlue;
XAllocNamedColor(dpy, cmap, arrowcolor, &color, &color);
gcv.foreground = color.pixel;
hintgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
} else {
gcv.foreground = WhitePixel(dpy, screen);
hintgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
}
}
#endif
#ifdef useXview
void init_arrow(unsigned long arrowcolor, int arrwidth, int arrheight)
{
XGCValues gcv;
long gcflags;
if (arrwidth >= 0 && arrwidth <= 30)
graphic.aw = arrwidth;
if (arrheight >= 0 && arrheight <= 30)
graphic.ah = arrheight;
if (graphic.aw <= 0 || graphic.ah <= 0) {
graphic.aw = graphic.ah = -1;
return; /* no arrows wanted */
}
gcv.background = BlackPixel(dpy, screen);
gcv.graphics_exposures = True;
gcflags = GCForeground | GCBackground | GCGraphicsExposures;
gcv.foreground = arrowcolor;
hintgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
}
#endif
/* draw an arrow with y-part */
static void polygon_y(int deltax, int deltay, int adx, int ady)
{
XPoint Poly[10];
Poly[0].x = rem_dx-deltax;
Poly[0].y = rem_dy-ady/2;
Poly[1].x = rem_dx-adx;
Poly[1].y = rem_dy-ady;
Poly[2].x = rem_dx;
Poly[2].y = rem_dy+ady;
Poly[3].x = rem_dx+adx;
Poly[3].y = rem_dy-ady;
Poly[4].x = rem_dx+deltax;
Poly[4].y = rem_dy-ady/2;
if (rem_dx-rem_sx > 0) { /* this is uncritical, since difference is */
Poly[5].x = rem_dx+deltax; /* either 0 or at least CARD_WIDTH */
Poly[5].y = rem_sy+deltay;
Poly[6].x = rem_sx-deltax;
Poly[6].y = rem_sy+deltay;
Poly[7].x = rem_sx-deltax;
Poly[7].y = rem_sy-deltay;
Poly[8].x = rem_dx-deltax;
Poly[8].y = rem_sy-deltay;
XFillPolygon(dpy, table, hintgc, Poly, 9, Complex, CoordModeOrigin);
Poly[9] = Poly[0];
XDrawLines(dpy, table, blackgc, Poly, 10, CoordModeOrigin);
} else if (rem_dx < rem_sx) {
Poly[5].x = rem_dx+deltax;
Poly[5].y = rem_sy-deltay;
Poly[6].x = rem_sx+deltax;
Poly[6].y = rem_sy-deltay;
Poly[7].x = rem_sx+deltax;
Poly[7].y = rem_sy+deltay;
Poly[8].x = rem_dx-deltax;
Poly[8].y = rem_sy+deltay;
XFillPolygon(dpy, table, hintgc, Poly, 9, Complex, CoordModeOrigin);
Poly[9] = Poly[0];
XDrawLines(dpy, table, blackgc, Poly, 10, CoordModeOrigin);
} else {
Poly[5].x = rem_sx+deltax;
Poly[5].y = rem_sy+deltay;
Poly[6].x = rem_sx-deltax;
Poly[6].y = rem_sy+deltay;
XFillPolygon(dpy, table, hintgc, Poly, 7, Complex, CoordModeOrigin);
Poly[7] = Poly[0];
XDrawLines(dpy, table, blackgc, Poly, 8, CoordModeOrigin);
}
}
/* draw an x-only arrow */
static void polygon_x(int deltax, int deltay, int adx, int ady)
{
XPoint Poly[10];
/* Pfeil: 1 */
/* 0 */
/* 2 */
/* 4 */
/* 3 */
Poly[0].x = rem_dx-adx/2;
Poly[0].y = rem_sy-deltay;
Poly[1].x = rem_dx-adx;
Poly[1].y = rem_sy-ady;
Poly[2].x = rem_dx+adx;
Poly[2].y = rem_sy;
Poly[3].x = rem_dx-adx;
Poly[3].y = rem_sy+ady;
Poly[4].x = rem_dx-adx/2;
Poly[4].y = rem_sy+deltay;
Poly[5].x = rem_sx-deltax;
Poly[5].y = rem_sy+deltay;
Poly[6].x = rem_sx-deltax;
Poly[6].y = rem_sy-deltay;
XFillPolygon(dpy, table, hintgc, Poly, 7, Complex, CoordModeOrigin);
Poly[7] = Poly[0];
XDrawLines(dpy, table, blackgc, Poly, 8, CoordModeOrigin);
}
#define UPDOWN_MINDIST (graphic.ya_h + graphic.ah + 1)
static void display_arrow(void)
{
/* build a polygon i.e. a arrow pointing from source to destination */
if (rem_dy >= rem_sy + UPDOWN_MINDIST) /* arrow up */
polygon_y(graphic.aw,-graphic.ah,graphic.ya_w, graphic.ya_h);
else if (rem_dy <= rem_sy - UPDOWN_MINDIST) /* arrow down */
polygon_y(graphic.aw,graphic.ah,graphic.ya_w,-graphic.ya_h);
else if (rem_dx >= rem_sx) /* arrow to the right */
polygon_x(graphic.aw,graphic.ah,graphic.xa_w,graphic.xa_h);
else /* arrow to the left */
polygon_x(-graphic.aw,graphic.ah,-graphic.xa_w,graphic.xa_h);
}
static void clear_arrow(void)
{ int a, d;
a = -1;
if (rem_sx < rem_dx) {
a = rem_sx; d = rem_dx - rem_sx;
} else if (rem_sx > rem_dx) {
a = rem_dx; d = rem_sx - rem_dx;
} else
d = a = -1;
if (a >= 0)
XCopyArea(dpy, arrow_storage_x, table, whitegc,
0, 0, d + 2 * graphic.aw + 1, 2 * graphic.ah + 1,
a - graphic.aw, rem_sy - graphic.ah);
if (rem_sy <= rem_dy - UPDOWN_MINDIST) {
a = rem_sy; d = rem_dy - rem_sy;
} else if (rem_sy >= rem_dy + UPDOWN_MINDIST) {
a = rem_dy; d = rem_sy - rem_dy;
} else {
d = a = -1; /* only horizontal part of arrow => y arrow */
XCopyArea(dpy, arrow_storage_z, table, whitegc,
0, 0, 2 * graphic.xa_w + 1, 2 * graphic.xa_h + 1, rem_dx-graphic.xa_w, rem_sy-graphic.xa_h);
}
if (a >= 0) {
XCopyArea(dpy, arrow_storage_y, table, whitegc,
0, 0, 2 * graphic.aw + 1, d + 2 * graphic.ah + 1,
rem_dx - graphic.aw, a - graphic.ah);
XCopyArea(dpy, arrow_storage_z, table, whitegc,
0, 0, 2 * graphic.ya_w + 1, 2 * graphic.ya_h + 1, rem_dx-graphic.ya_w, rem_dy-graphic.ya_h);
}
rem_sx = -1;
}
static void save_background(void)
{
/* save the background */
int a, d;
a = -1;
if (rem_sx < rem_dx) {
a = rem_sx; d = rem_dx - rem_sx;
} else if (rem_sx > rem_dx) {
a = rem_dx; d = rem_sx - rem_dx;
} else
d = a = -1;
if (a >= 0) {
int len;
len = d + 2 * graphic.aw + 1;
if (len > size_x) { /* Create a larger Pixmap for saving */
XFreePixmap(dpy, arrow_storage_x);
arrow_storage_x = XCreatePixmap(dpy, table,
size_x = len, 2 * graphic.ah+1, DefaultDepth(dpy, screen));
}
XCopyArea(dpy, table, arrow_storage_x, whitegc,
a - graphic.aw, rem_sy - graphic.ah,
len, 2 * graphic.ah + 1, 0, 0);
}
if (rem_sy <= rem_dy - UPDOWN_MINDIST) {
a = rem_sy; d = rem_dy - rem_sy;
} else if (rem_sy >= rem_dy + UPDOWN_MINDIST) {
a = rem_dy; d = rem_sy - rem_dy;
} else {
d = a = -1; /* only horizontal part of arrow */
XCopyArea(dpy, table, arrow_storage_z, whitegc,
rem_dx-graphic.xa_w, rem_sy-graphic.xa_h, 2 * graphic.xa_w + 1, 2 * graphic.xa_h + 1, 0, 0);
}
if (a >= 0) {
int height;
height = d + 2 * graphic.ah + 1;
if (size_y < height) {
XFreePixmap(dpy, arrow_storage_y);
arrow_storage_y = XCreatePixmap(dpy, table,
2 * graphic.aw+1, size_y = height, DefaultDepth(dpy, screen));
}
XCopyArea(dpy, table, arrow_storage_y, whitegc,
rem_dx - graphic.aw, a - graphic.ah,
2 * graphic.aw + 1, height, 0, 0);
XCopyArea(dpy, table, arrow_storage_z, whitegc,
rem_dx-graphic.ya_w, rem_dy-graphic.ya_h, 2 * graphic.ya_w + 1, 2 * graphic.ya_h + 1, 0, 0);
}
}
static void compute_rem(void) {
Pileindex srcpile;
struct pile *p;
p = graphic.pile + game.arrow_dstpile;
srcpile = getpile(game.arrow_srcind);
rem_sx = graphic.pile[srcpile].x + CARD_WIDTH/2;
rem_sy = graphic.pile[srcpile].y + CARD_HEIGHT/2;
if (game.piletype[srcpile] == Slot) {
int y = graphic.cardy[game.arrow_srcind];
rem_sy += y;
if (game.arrow_srcind != INDEX_OF_LAST_CARD(srcpile))
rem_sy += (graphic.cardy[game.arrow_srcind+1] - y + 1) / 2
- CARD_HEIGHT/2;
}
rem_dx = p->x + CARD_WIDTH/2;
rem_dy = p->y + CARD_HEIGHT/2;
if (game.piletype[game.arrow_dstpile] == Slot && !EMPTY(game.arrow_dstpile))
rem_dy += graphic.cardy[INDEX_OF_LAST_CARD(game.arrow_dstpile)];
if (rem_sy > graphic.height-2)
rem_sy = graphic.height-2;
if (rem_dy > graphic.height-2)
rem_dy = graphic.height-2;
}
void show_arrow(int on) {
if (graphic.aw <= 0) /* no arrows active */
return;
if (!arrow_storage_x) {
arrow_storage_x = XCreatePixmap(dpy, table, size_x = graphic.width,
2 * graphic.ah+1, DefaultDepth(dpy, screen));
arrow_storage_y = XCreatePixmap(dpy, table, 2 * graphic.aw+1,
size_y = graphic.height, DefaultDepth(dpy, screen));
arrow_storage_z = XCreatePixmap(dpy, table, 2 * max(graphic.xa_w,
graphic.ya_w) + 1, 2 * max(graphic.xa_h, graphic.ya_h) + 1,
DefaultDepth(dpy, screen));
}
if (on) { /* calculate new arrow position */
#ifdef DEBUG
if (on == 2)
fprintf(stderr, "arrow(2): srcind = %d\n", game.arrow_srcind);
#endif
if (game.arrow_srcind < 0)
return;
if (on == 1) {
compute_rem();
save_background();
}
display_arrow();
#ifdef useXview
xv_set(xv_default_server, SERVER_SYNC, FALSE, 0);
#else
XFlush(dpy);
#endif
} else {
game.arrow_srcind = -1; /* no valid arrow now */
if (rem_sx < 0)
return; /* no arrow was visible */
clear_arrow();
}
}